/*
 * Copyright 2018-present KunMinX
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nsgf.library.ui.page;

import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.ViewModel;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;

import com.kunminx.architecture.ui.scope.ViewModelScope;
import com.nsgf.library.R;
import com.nsgf.library.base.BaseApplication;
import com.nsgf.library.base.DataBindingFragment;
import com.nsgf.skjz.utils.CustomToast;
import com.nsgf.skjz.utils.SPUtil;
import com.nsgf.skjz.utils.SpKey;
import com.nsgf.skjz.utils.ToastUtils;
import com.nsgf.skjz.utils.Utils;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Objects;

import javax.net.ssl.SSLHandshakeException;

import retrofit2.HttpException;


/**
 * Create by GC at 24/9/11
 */
public abstract class BaseFragment extends DataBindingFragment implements LocationListener,
        View.OnClickListener {

    private final ViewModelScope mViewModelScope = new ViewModelScope();

    //TODO tip 1: DataBinding 严格模式（详见 DataBindingFragment - - - - - ）：
    // 将 DataBinding 实例限制于 base 页面中，默认不向子类暴露，
    // 通过这方式，彻底解决 View 实例 Null 安全一致性问题，
    // 如此，View 实例 Null 安全性将和基于函数式编程思想的 Jetpack Compose 持平。


    //TODO tip 2: Jetpack 通过 "工厂模式" 实现 ViewModel 作用域可控，
    //目前我们在项目中提供了 Application、Activity、Fragment 三个级别的作用域，
    //值得注意的是，通过不同作用域 Provider 获得 ViewModel 实例非同一个，
    //故若 ViewModel 状态信息保留不符合预期，可从该角度出发排查 是否眼前 ViewModel 实例非目标实例所致。


    protected <T extends ViewModel> T getFragmentScopeViewModel(@NonNull Class<T> modelClass) {
        return mViewModelScope.getFragmentScopeViewModel(this, modelClass);
    }

    protected <T extends ViewModel> T getActivityScopeViewModel(@NonNull Class<T> modelClass) {
        return mViewModelScope.getActivityScopeViewModel(mActivity, modelClass);
    }

    protected <T extends ViewModel> T getApplicationScopeViewModel(@NonNull Class<T> modelClass) {
        return mViewModelScope.getApplicationScopeViewModel(modelClass);
    }

    protected NavController nav() {
        return NavHostFragment.findNavController(this);
    }

    protected void toggleSoftInput() {
        InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
    }

    protected void openUrlInBrowser(String url) {
        Uri uri = Uri.parse(url);
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }

    protected Context getApplicationContext() {
        return mActivity.getApplicationContext();
    }


    public void Error(Throwable e) {
        String error = null;
        try {

            if (e instanceof SocketTimeoutException) {//请求超时
                error = "网络连接超时";
            } else if (e instanceof ConnectException) {//网络连接超时
                error = "网络连接超时";
            } else if (e instanceof SSLHandshakeException) {//安全证书异常
                error = "安全证书异常";
            } else if (e instanceof HttpException) {//请求的地址不存在
                int code = ((HttpException) e).code();
                if (code == 504) {
                    error = "网络异常，请检查您的网络状态";
                } else if (code == 502) {
                    error = e.getMessage();
                } else if (code == 404) {
                    error = "请求的地址不存在";
                } else {
                    error = "请求失败";
                }
            } else if (e instanceof UnknownHostException) {//域名解析失败
                error = "域名解析失败";
            } else {
                error = e.getMessage();
            }
            Looper.prepare();
            Toast.makeText(BaseApplication.getInstance(), error, Toast.LENGTH_SHORT).show();
            Looper.loop();

        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }


    /**
     *  获取请求异常
     * @param e
     * @return
     */
    public String getErrorMsg(Throwable e) {
        String error = null;
        try {

            if (e instanceof SocketTimeoutException) {//请求超时
                error = "网络连接超时";
            } else if (e instanceof ConnectException) {//网络连接超时
                error = "网络连接超时";
            } else if (e instanceof SSLHandshakeException) {//安全证书异常
                error = "安全证书异常";
            } else if (e instanceof HttpException) {//请求的地址不存在
                int code = ((HttpException) e).code();
                if (code == 504) {
                    error = "网络异常，请检查您的网络状态";
                } else if (code == 502) {
                    error = e.getMessage();
                } else if (code == 404) {
                    error = "请求的地址不存在";
                } else {
                    error = "请求失败";
                }
            } else if (e instanceof UnknownHostException) {//域名解析失败
                error = "域名解析失败";
            } else {
                error = e.getMessage();
            }
            return error;

        } catch (Exception e2) {
            e2.printStackTrace();
            return "";
        }
    }


    public LocationManager locationManager;
    /**
     * 发起定位
     *
     * @param realTime 是否实时定位
     */
    public void startLocation(boolean realTime) {
        if (null == locationManager) {
            locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        }
        // 检查是否已经给予位置权限
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            // 请求位置更新
            if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED &&
                    ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION)
                            != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, 0x123);
                return;
            }
            // 请求位置更新，最小时间间隔和最小距离变化后更新
            if (realTime) {
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, this);
            } else {
                locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, this, null);
            }
        } else {
            // 提示用户开启GPS
            ToastUtils.showLongToast("请打开定位权限");
            if (realTime)
                showMissingPermissionDialog();
        }
    }


    /**
     * 显示提示信息
     *
     * @since 2.5.0
     */
    private void showMissingPermissionDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(R.string.notifyTitle);
        builder.setMessage(R.string.notifyMsg);

        // 拒绝, 退出应用
        builder.setNegativeButton(R.string.cancel,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });

        builder.setPositiveButton(R.string.setting,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        startAppSettings();
                    }
                });

        builder.setCancelable(false);

        builder.show();
    }

    /**
     * 启动应用的设置
     *
     * @since 2.5.0
     */
    public void startAppSettings() {
        Intent intent = new Intent(
                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
        startActivity(intent);
    }

    @Override
    public void onLocationChanged(@NonNull Location location) {

        // 当位置更新时，这里处理位置信息
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();

        SPUtil.put(SpKey.KEY_LATITUDE, String.valueOf(latitude), getActivity());
        SPUtil.put(SpKey.KEY_LONGITUDE, String.valueOf(longitude), getActivity());
        Log.e("==============", latitude + "," + longitude);
    }


    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // 处理状态变化
    }

    @Override
    public void onProviderEnabled(String provider) {
        // 处理提供者启用
    }

    @Override
    public void onProviderDisabled(String provider) {
        // 处理提供者禁用
    }

    @Override
    public void onClick(View view) {

    }


    public void showToast(final String txt) {
        requireActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                CustomToast.showToast(Utils.getApp().getApplicationContext(), txt);
            }
        });
    }
}
